#include "TransmitterManager.hpp"
#include "cbb_log_api.h"
#include "make_unique.hpp"
TransmitterManager::TransmitterManager() {}

TransmitterManager::~TransmitterManager() {
    for (auto &cameraTransmitters : m_transmitters) {
        cameraTransmitters.clear();
    }
    m_transmitters.clear();
}

bool TransmitterManager::initializeTransmitters(int cameraId, const std::vector<TransportConfig> &configs) {
    if (cameraId >= 0 && static_cast<std::size_t>(cameraId) >= m_transmitters.size()) {
        m_transmitters.resize(cameraId + 1);
    }

    auto &cameraTransmitters = m_transmitters[cameraId];
    cameraTransmitters.clear();

    for (const auto &config : configs) {
        auto transmitter = std::make_unique<NetworkTransmitter>(cameraId);
        if (transmitter->initialize(config)) {
            transmitter->start();
            cameraTransmitters.emplace_back(std::move(transmitter), config);
            CbbLogInfo("Transmitter initialized for camera %d, protocol: %d, address: %s, port: %d",
                       cameraId, static_cast<int>(config.protocol), config.address.c_str(), config.port);
        } else {
            CbbLogError("Failed to initialize transmitter for camera %d", cameraId);
            return false;
        }
    }

    return true;
}

int TransmitterManager::sendData(int cameraId, int channelId, const NetworkFrameData &frameData) {
    if (cameraId < 0 || static_cast<std::size_t>(cameraId) >= m_transmitters.size()) {
        CbbLogError("Invalid camera ID: %d", cameraId);
        return -1;
    }

    auto &cameraTransmitters = m_transmitters[cameraId];
    if (channelId < 0 || static_cast<std::size_t>(channelId) >= cameraTransmitters.size()) {
        CbbLogError("Invalid channel ID: %d for camera %d", channelId, cameraId);
        return -1;
    }

    return cameraTransmitters[channelId].transmitter->sendData(frameData);
}

void TransmitterManager::destroyTransmitters(int cameraId) {
    if (cameraId >= 0 && static_cast<std::size_t>(cameraId) < m_transmitters.size()) {
        m_transmitters[cameraId].clear();
    }
}

NetworkTransmitter *TransmitterManager::getTransmitter(int cameraId, CameraTranDirectionE_t direction) {
    if (cameraId < 0 || static_cast<size_t>(cameraId) >= m_transmitters.size()) {
        return nullptr;
    }

    auto &transmitters = m_transmitters[cameraId];
    for (auto &instance : transmitters) {
        if (instance.config.direction == direction) {
            return instance.transmitter.get();
        }
    }

    return nullptr;
}